package com.syl.auth.handle;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.syl.auth.constant.AuthConstant;
import com.syl.auth.model.ResultVO;
import com.syl.auth.model.SmallUserInfo;
import com.syl.auth.utils.SecurityUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @ClassName SmallAuthenticationSuccessHandler
 * @Description 登录成功处理器
 * @Author YunLong
 * @Date 2023/5/3 14:05
 */
@Component
public class SmallAuthenticationSuccessHandler implements AuthenticationSuccessHandler {

    @Autowired
    ApplicationContext context;

    private LoginSuccessResultHandler resultHandler = new DefaultResultHandler();


    @PostConstruct
    public void init() {
        Map<String, LoginSuccessResultHandler> beansMap = context.getBeansOfType(LoginSuccessResultHandler.class);

        Collection<LoginSuccessResultHandler> values = beansMap.values();
        if (!CollectionUtils.isEmpty(values)) {
            LoginSuccessResultHandler[] array = values.toArray(new LoginSuccessResultHandler[0]);
            resultHandler = array[0];
        }
    }


    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        response.setContentType("application/json;charset=utf-8");
        PrintWriter out = response.getWriter();
        SmallUserInfo smallUserInfo = (SmallUserInfo) authentication.getPrincipal();

        if (smallUserInfo == null) {
            throw new AuthenticationServiceException("处理认证结果失败。fastUserInfo is null");
        }

        HashMap<String, Object> claims = new HashMap<>();
        String roles = smallUserInfo.getAuthorities()
                .stream()
                .map(GrantedAuthority::getAuthority)
                .collect(Collectors.joining(","));
        Long userId = smallUserInfo.getId();

        claims.put(AuthConstant.USER_ID, userId);
        claims.put(AuthConstant.USERNAME, smallUserInfo.getUsername());
        claims.put(AuthConstant.ORG_ID, smallUserInfo.getOrgId());
        claims.put(AuthConstant.ORG_NAME, smallUserInfo.getOrgName());
        claims.put(AuthConstant.ROLES_ID_KEY, roles);

        String token = SecurityUtil.createToken(claims);


        // 处理返回值
        Object result = resultHandler.handleResult(smallUserInfo, token);
        String s = new ObjectMapper().writeValueAsString(result);
        out.write(s);
        out.flush();
        out.close();
    }

    public static class DefaultResultHandler implements LoginSuccessResultHandler {

        @Override
        public Object handleResult(SmallUserInfo fastUserInfo, String token) {
            return ResultVO.success(token);
        }
    }
}
